package com.module.bp.view;

import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.lang.reflect.Method;

import com.dalonedrau.jogl.engine.GameApplet;
import com.dalonedrau.jogl.engine.GameState;
import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.jogl.engine.Interface;
import com.dalonedrau.jogl.opengl.View;
import com.dalonedrau.jogl.opengl.sprite.BasicSpriteObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteBase;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObjectFactory;
import com.dalonedrau.jogl.opengl.ui.Label;
import com.dalonedrau.jogl.opengl.ui.UIFactory;
import com.dalonedrau.jogl.opengl.ui.panel.LandscapePagePanel;
import com.dalonedrau.jogl.opengl.ui.panel.Panel;
import com.dalonedrau.jogl.util.UtilityMethods;

/**
 * The title screen view.
 * @author Donald
 */
public final class LoadingView implements View {
	/** the one and only instance of the <code>LoadingView</code> class. */
	private static LoadingView	instance;
	/**
	 * Gives access to the singleton instance of {@link LoadingView}.
	 * @return {@link LoadingView}
	 */
	public static LoadingView getInstance() {
		if (LoadingView.instance == null) {
			LoadingView.instance = new LoadingView();
		}
		return LoadingView.instance;
	}
	/** the next state after rendering the "Loading..." screen. */
	private int		nextState	= -1;
	/** the UI container. */
	private Panel	panel;
	/** flag indicating initialization has been completed. */
	private boolean	runInit		= false;
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleKeyEvent(final KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_ESCAPE:
			System.out.println("esc");
			GameApplet.getInstance().exit();
			break;
		default:
			break;
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMouseOver(final float x, final float y) {}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMousePress(final MouseEvent e, final float x,
			final float y) { }
	/**
	 * Initializes the {@link View}.
	 * @throws Exception if an error occurs
	 */
	private void init() throws Exception {
		System.out.println("init");
		SpriteBase sb = new BasicSpriteObject();
		SpriteImageObject img =
				SpriteImageObjectFactory.getInstance().getImageByName(
						"symbol_wait");
		sb.setImageRefId(img.getRefId());
		sb.setWidth(img.getWidth());
		sb.setHeight(img.getHeight());
		Label l0 = new Label(sb);
		Label l1 = UIFactory.getInstance().getStandardH1Label("Loading...");
		panel = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		panel.addChild(l0);
		panel.addChild(l1);
		Point pt = UtilityMethods.getInstance().centerComponentInFrame(panel);
		panel.setPosition(pt.x, pt.y, 0.0f);
		panel.setVisible(true);
		runInit = true;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		if (!runInit) {
			try {
				init();
			} catch (Exception ex) {
				ErrorHandler.getInstance().fatalError(ex);
			}
		}
		Interface.getInstance().assignViewFlag(
				GlobalConsts.VW_LOADWINDOW);
		panel.prepareForRendering();
		if (!rendered) {
			// render at least once before executing load action
			rendered = true;
		} else {
			// execute loading action
			action.execute();
		}
		
	}
	public void setLoadAction(final Object instance, final Method method, 
			final Object[] args) {
		if (action == null) {
			action = new LoadAction();
		}
		action.setInstance(instance);
		action.setMethod(method);
		action.setArgs(args);
	}
	private LoadAction action;
	void goToNextState() {
		if (nextState != -1) {
			Interface.getInstance().removeViewFlag(
					GlobalConsts.VW_LOADWINDOW);
			GameState.getInstance().setCurrentState(nextState);
			nextState = -1;
		}		
	}
	private boolean rendered = false;
	/**
	 * Sets the rendered
	 * @param rendered the rendered to set
	 */
	public void setRendered(boolean rendered) {
		this.rendered = rendered;
	}
	/**
	 * Sets the next state after rendering the "Loading..." screen.
	 * @param val the next state to set
	 */
	public void setNextState(final int val) {
		nextState = val;
	}
}
class LoadAction {
	private Method method;
	private Object instance;
	private Object[] args;
	/**
	 * Sets the method
	 * @param method the method to set
	 */
	public void setMethod(Method method) {
		this.method = method;
	}
	/**
	 * Sets the instance
	 * @param instance the instance to set
	 */
	public void setInstance(Object instance) {
		this.instance = instance;
	}
	/**
	 * Sets the args
	 * @param args the args to set
	 */
	public void setArgs(Object[] args) {
		this.args = args;
	}
	void execute() {
		try {
			method.invoke(instance, args);
			LoadingView.getInstance().goToNextState();
		} catch (Exception ex) {
			ErrorHandler.getInstance().fatalError(ex);
		}
	}
}
